﻿namespace Practices.IdentityProvider {
    using System;
    using System.Collections.Generic;
    using System.IdentityModel;
    using System.IdentityModel.Configuration;
    using System.IdentityModel.Protocols.WSTrust;
    using System.Linq;
    using System.Security.Claims;
    using System.Web;
    using System.Xml;

    public class ContosoSecurityTokenService : SecurityTokenService {
        public ContosoSecurityTokenService(SecurityTokenServiceConfiguration configuration)
            : base(configuration) {
        }

        protected override Scope GetScope(ClaimsPrincipal principal, RequestSecurityToken request) {
            this.ValidateAppliesTo(request.AppliesTo);
            Scope scope = new Scope(request.AppliesTo.Uri.OriginalString, SecurityTokenServiceConfiguration.SigningCredentials);

            scope.TokenEncryptionRequired = false;
            scope.SymmetricKeyEncryptionRequired = false;

            if (string.IsNullOrEmpty(request.ReplyTo)) {
                //scope.ReplyToAddress = scope.AppliesToAddress;
                scope.ReplyToAddress = IdentityHelper.ReplyToAddress(scope.AppliesToAddress);                
            } else {
                scope.ReplyToAddress = request.ReplyTo;
            }

            return scope;
        }

        protected override ClaimsIdentity GetOutputClaimsIdentity(ClaimsPrincipal principal, RequestSecurityToken request, Scope scope) {
            if (principal == null) {
                throw new InvalidRequestException("The Caller's Principal is null.");
            }
            ClaimsIdentity outputIdentity = new ClaimsIdentity();
            outputIdentity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, "urn:oasis:names:tc:SAML:1.0:am:password"));
            outputIdentity.AddClaim(new Claim(ClaimTypes.AuthenticationInstant, XmlConvert.ToString(DateTime.Now, "yyyy-MM-ddTHH:mm:ssZ"), ClaimValueTypes.DateTime));
            outputIdentity.AddClaims(principal.Claims);
            return outputIdentity;
        }

        private void ValidateAppliesTo(EndpointReference appliesTo) {
            if (appliesTo == null) {
                throw new InvalidRequestException("The AppliesTo is null.");
            }
        }

    }
}